package com.tompai.echarts.logger;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * @author 
 * @version 
 * @date 2021/2/12
 */
@Aspect
public class LogAspect {

	private static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class);
	private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
	private static final String STRING_START = "===========";
	private static final String STRING_END = "============";

	@Pointcut(value = "@annotation(com.tompai.echarts.logger.Log)")
	public void logAspect() {
	}

	@Around("logAspect()")
	public Object around(ProceedingJoinPoint joinPoint) {
		try {
			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			Method method = signature.getMethod();
			Class<?> targetClass = method.getDeclaringClass();

			StringBuffer classAndMethod = new StringBuffer();

			Log classAnnotation = targetClass.getAnnotation(Log.class);
			Log methodAnnotation = method.getAnnotation(Log.class);

			if (classAnnotation != null) {
				if (classAnnotation.ignore()) {
					return joinPoint.proceed();
				}
				classAndMethod.append(classAnnotation.value()).append("-");
			}

			if (methodAnnotation != null) {
				if (methodAnnotation.ignore()) {
					return joinPoint.proceed();
				}
				classAndMethod.append(methodAnnotation.value());
			}

			String target = targetClass.getName() + "#" + method.getName();
			String params = JSONObject.toJSONStringWithDateFormat(joinPoint.getArgs(), dateFormat,
					SerializerFeature.WriteMapNullValue);

			LOGGER.info(STRING_START + "{} 开始调用--> {} 参数:{}" + STRING_END, classAndMethod.toString(), target, params);

			long start = System.currentTimeMillis();
			Object result = joinPoint.proceed();
			long timeConsuming = System.currentTimeMillis() - start;

			LOGGER.info(STRING_START + "{} 调用结束<-- {} 返回值:{} 耗时:{}ms" + STRING_END, classAndMethod.toString(), target,
					JSONObject.toJSONStringWithDateFormat(result, dateFormat, SerializerFeature.WriteMapNullValue),
					timeConsuming);
			return result;
		} catch (Throwable throwable) {
			LOGGER.error(throwable.getMessage(), throwable);
		}
		return null;
	}
}
